/*
 * MultirootSolver.h
 *
 *  Created on: 23 Jun 2011
 *      Author: allan
 */

#ifndef MULTIROOTSOLVER_H_
#define MULTIROOTSOLVER_H_

// C++ includes
#include <memory>
using namespace std;

// Eigen includes
#include <Eigen/Dense>
using namespace Eigen;

class MultirootProblem
{
public:
	virtual void Function(const VectorXd& x, VectorXd& F) = 0;
	
	virtual void Jacobian(const VectorXd& x, MatrixXd& J) = 0;
	
	virtual void FunctionJacobian(const VectorXd& x, VectorXd& F, MatrixXd& J) { Function(x, F); Jacobian(x, J); }
};

enum MultirootAlgorithm
{
	Hybridj, 
	Hybridsj, 
	StandardNewton, 
	ModifiedNewton 
};

class MultirootSolverImp;

class MultirootSolver
{
public:
	MultirootSolver();
	
	MultirootSolver(unsigned dimension, MultirootAlgorithm algorithm = ModifiedNewton);
	
	~MultirootSolver();
	
	void Initialiaze(unsigned dimension, MultirootAlgorithm algorithm = ModifiedNewton);
	
	void SetSolverOptions(double tolerance, unsigned maxiterations);
	
	bool Iterate(MultirootProblem& problem, VectorXd& x);
	
	bool Solve(MultirootProblem& problem, VectorXd& x);
	
private:
	std::unique_ptr<MultirootSolverImp> imp;
};

#endif /* MULTIROOTSOLVER_H_ */
